`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/11/20 21:20:32
// Design Name: 
// Module Name: gmii_ram
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module gmii_ram(
    input           i_pre_clk       ,
    input  [7 :0]   i_pre_data      ,
    input           i_pre_valid     ,

    input           i_post_clk      ,
    output [7 :0]   o_post_data     ,
    output          o_post_valid    
);

reg  [7 :0]         ro_post_data =0 ;
reg                 ro_post_valid=0 ;
reg  [10:0]         r_bram_addra =0 ;
reg  [15:0]         r_pre_len    =0 ;
reg                 ri_pre_valid =0 ;
reg  [10:0]         r_bram_addrb =0 ;
reg                 r_bram_enb   =0 ;
reg                 r_bram_enb_1d=0 ;
reg                 r_fifo_prden =0 ;
reg                 r_fifo_prden_1d=0;
reg                 r_post_run   =0 ;
reg  [15:0]         r_post_cnt   =0 ;
reg  [15:0]         r_post_len   =0 ;

wire                w_pre_valid_pos ;
wire                w_pre_valid_neg ;
wire [7 :0]         w_bram_doutb    ;
wire [15:0]         w_fifo_pdout    ;
wire                w_fifo_prefull  ;
wire                w_fifo_pempty   ;

assign o_post_data  = ro_post_data  ;
assign o_post_valid = ro_post_valid ;
assign w_pre_valid_pos = i_pre_valid & !ri_pre_valid;
assign w_pre_valid_neg = !i_pre_valid & ri_pre_valid;

asdpram_8x2048 asdpram_8x2048_inst (
  .clka             (i_pre_clk          ),
  .ena              (i_pre_valid        ),
  .wea              (i_pre_valid        ),
  .addra            (r_bram_addra       ),
  .dina             (i_pre_data         ),
  .clkb             (i_post_clk         ),
  .enb              (r_bram_enb         ),
  .addrb            (r_bram_addrb       ),
  .doutb            (w_bram_doutb       ) 
);

asfifo_16x32 asfifo_16x32_inst (
  .wr_clk           (i_pre_clk          ),
  .rd_clk           (i_post_clk         ),
  .din              (r_pre_len          ),
  .wr_en            (w_pre_valid_neg    ),
  .rd_en            (r_fifo_prden       ),
  .dout             (w_fifo_pdout       ),
  .full             (w_fifo_prefull     ),
  .empty            (w_fifo_pempty      ) 
);


always@(posedge i_pre_clk)
begin
    ri_pre_valid <= i_pre_valid;
end
always@(posedge i_pre_clk)
begin
    if(i_pre_valid && r_bram_addra == 2048 - 1)
        r_bram_addra <= 'd0;
    else if(i_pre_valid)
        r_bram_addra <= r_bram_addra + 1;
    else 
        r_bram_addra <= r_bram_addra;
end

always@(posedge i_pre_clk)
begin
    if(w_pre_valid_neg)
        r_pre_len <= 'd0;
    else if(i_pre_valid)
        r_pre_len <= r_pre_len + 1;
    else 
        r_pre_len <= r_pre_len;
end

/*----post----*/

always@(posedge i_post_clk)
begin
    r_fifo_prden_1d <= r_fifo_prden;
    r_bram_enb_1d   <= r_bram_enb;
end

always@(posedge i_post_clk)
begin
    if(r_fifo_prden)
        r_fifo_prden <= 'd0;
    else if(!r_post_run && !w_fifo_pempty)
        r_fifo_prden <= 'd1;
    else 
        r_fifo_prden <= 'd0;
end

always@(posedge i_post_clk)
begin
    if(r_fifo_prden_1d)
        r_post_len <= w_fifo_pdout;
    else 
        r_post_len <= r_post_len;
end

always@(posedge i_post_clk)
begin
    if(r_bram_enb && r_post_cnt == r_post_len - 1)
        r_post_run <= 'd0;
    else if(!r_post_run && !w_fifo_pempty)
        r_post_run <= 'd1;
    else 
        r_post_run <= r_post_run;
end

always@(posedge i_post_clk)
begin
    if(r_bram_enb && r_bram_addrb == 2048 - 1)
        r_bram_addrb <= 'd0;
    else if(r_bram_enb)
        r_bram_addrb <= r_bram_addrb + 1;
    else 
        r_bram_addrb <= r_bram_addrb;
end
  
always@(posedge i_post_clk)
begin
    if(r_bram_enb && r_post_cnt == r_post_len - 1)
        r_bram_enb <= 'd0;
    else if(r_fifo_prden_1d)
        r_bram_enb <= 'd1;
    else 
        r_bram_enb <= r_bram_enb;
end

always@(posedge i_post_clk)
begin
    if(r_bram_enb && r_post_cnt == r_post_len - 1)
        r_post_cnt <= 'd0;
    else if(r_bram_enb)
        r_post_cnt <= r_post_cnt + 1;
    else 
        r_post_cnt <= r_post_cnt;
end

always@(posedge i_post_clk)
begin
    ro_post_data  <= w_bram_doutb   ;
    ro_post_valid <= r_bram_enb_1d  ;
end






endmodule
